﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Configuration;
using System.Globalization;
using Gollie.WebCache;

namespace Gollie.Invoice
{
	public class InvoiceData : CacheFileDependency
	{
		private static string cacheName = "data_invoicevendorconfig";

		Dictionary<uint, FeeCollection> Fees = new Dictionary<uint, FeeCollection>();

		public InvoiceData()
			: base(ConfigurationManager.AppSettings["InvoicePath"])
		{
			this.Init();
		}

		private void Init()
		{
			XmlDocument doc = new XmlDocument();

			doc.Load(this.DependencyPath);

			XmlNodeList nodes = doc.SelectNodes("/gollie/invoice/*");

			this.Read(nodes);
		}

		private void Read(XmlNodeList nodes)
		{
			foreach (XmlNode node in nodes)
			{
				switch (node.LocalName)
				{
					case "fees":
						this.ReadFees(node);
						break;
					case "minimumfeeperdeposit":
						this.MinimumFeePerDeposit = XmlConvert.ToDecimal(node.Attributes["value"].Value);
						break;
					case "vat":
						this.VatPercentage = XmlConvert.ToDecimal(node.Attributes["percentage"].Value);
						break;
					default:
						throw new XmlException("Unknown node in invoice.xml: " + node.LocalName);
				}
			}
		}

		private void ReadFees(XmlNode node)
		{
			foreach (XmlNode vendorFeeNode in node.ChildNodes)
			{
				uint vendorId = 0;
				switch (vendorFeeNode.LocalName)
				{
					case "vendor": vendorId = XmlConvert.ToUInt32(vendorFeeNode.Attributes["id"].Value);
						break;
					case "default": vendorId = 0;
						break;
					default:
						throw new XmlException("Unknown node in invoice.xml: " + vendorFeeNode.LocalName);
				}

				var fees = new FeeCollection();
				fees.Read(vendorFeeNode);

				try
				{
					this.Fees.Add(vendorId, fees);
				}
				catch (ArgumentException)
				{
					throw new XmlException("Duplicate vendorid in invoice.xml: " + vendorFeeNode.LocalName + ": " + vendorId.ToString());
				}
			}
		}

		public static InvoiceData Instance
		{
			get
			{
				return DataCache.GetCacheableObject<InvoiceData>(cacheName);
			}
		}

		public FeeCollection GetFees(uint vendorId)
		{
			FeeCollection fc;
			if (this.Fees.TryGetValue(vendorId, out fc) == false)
				fc = this.Fees[0];

			return fc;
		}

		public decimal MinimumFeePerDeposit
		{
			get;
			private set;
		}

		public decimal VatPercentage
		{
			get;
			private set;
		}
	}
}
